package com.zyd.blog.homeart.util;

import me.zhyd.oauth.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 请求计时拦截器
 * @author loop
 */
public class TimekeepingInterceptor implements HandlerInterceptor {

    private static final String UN_KNOWM = "unKnown";

    private static Logger logger = LoggerFactory.getLogger(TimekeepingInterceptor.class);

    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    /**
     * 拦截前处理
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        threadLocal.set(System.currentTimeMillis());
        return true;
    }

    /**
     * 拦截后处理
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 全部完成后处理
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        String ip = this.getRemoteIp(httpServletRequest);
        String url = httpServletRequest.getRequestURL().toString();
        logger.info("{}[请求的信息:{}, 请求用时：{}ms]", url, ip, (System.currentTimeMillis() - threadLocal.get()));
    }

    /**
     * 获取远程请求IP地址)
     */
    private String getRemoteIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(ip) && !UN_KNOWM.equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtils.isNotEmpty(ip) && !UN_KNOWM.equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }
}